package com.tomecode.tools.maven.settings.gui.frm;

import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.grouplayout.GroupLayout;
import org.eclipse.swt.layout.grouplayout.LayoutStyle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import com.tomecode.tools.maven.settings.gui.images.ImageFactory;
import com.tomecode.tools.maven.settings.gui.utils.GuiUtils;
import com.tomecode.tools.maven.settings.gui.utils.SWTResourceManager;
import com.tomecode.tools.maven.settings.model.ChecksumPolicy;
import com.tomecode.tools.maven.settings.model.Layout;
import com.tomecode.tools.maven.settings.model.Repository;

/**
 * Dialog for editing repository
 * 
 * @author Tomas Frastia
 * @see http://www.tomecode.com or
 *      http://code.google.com/p/maven-settings-editor/
 * 
 */
public final class FrmRepository extends Dialog {

	private Repository newRepository;
	private Shell shlRepository;
	private List<Repository> listOfRepositories;
	private Repository existsRepository;
	private Text textID;
	private Text textName;
	private Text textURL;
	private Text textSnapshotsUpdatePolicy;
	private Text textReleasesUpdatePolicy;
	private Label labelWarning;
	private Button buttonTestURL;

	/**
	 * Create the dialog.
	 * 
	 * @param parent
	 * @param style
	 */
	public FrmRepository(Shell parent, List<Repository> listOfRepositories) {
		super(parent, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
		setText("Repository");
		this.listOfRepositories = listOfRepositories;
	}

	/**
	 * Open the dialog.
	 * 
	 * @return the result
	 */
	public final Repository open(Repository existsRepository) {
		createContents(existsRepository);
		shlRepository.open();
		shlRepository.layout();
		Display display = getParent().getDisplay();
		while (!shlRepository.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return newRepository;
	}

	/**
	 * Create contents of the dialog.
	 */
	private final void createContents(Repository existsRepository) {
		this.existsRepository = existsRepository;
		shlRepository = new Shell(getParent(), getStyle());
		shlRepository.setImage(ImageFactory.MAVEN_SETTINGS_EDITOR_16);
		shlRepository.setSize(575, 468);
		final Repository resultRepository;
		if (existsRepository == null) {
			shlRepository.setText("New Repository");
			resultRepository = new Repository();
		} else {
			shlRepository.setText("Edit Repository");
			resultRepository = new Repository(existsRepository);
		}

		Composite composite = new Composite(shlRepository, SWT.NONE);
		GroupLayout gl_shlRepository = new GroupLayout(shlRepository);
		gl_shlRepository.setHorizontalGroup(gl_shlRepository.createParallelGroup(GroupLayout.LEADING).add(composite, GroupLayout.DEFAULT_SIZE, 569, Short.MAX_VALUE));
		gl_shlRepository.setVerticalGroup(gl_shlRepository.createParallelGroup(GroupLayout.LEADING).add(composite, GroupLayout.DEFAULT_SIZE, 443, Short.MAX_VALUE));

		final Button btnCancel = new Button(composite, SWT.NONE);
		btnCancel.addSelectionListener(new SelectionAdapter() {
			public final void widgetSelected(SelectionEvent e) {
				shlRepository.close();
			}

		});
		btnCancel.setText("Cancel");
		final Button btnSave = new Button(composite, SWT.NONE);

		btnSave.addSelectionListener(new SelectionAdapter() {
			public final void widgetSelected(SelectionEvent e) {
				newRepository = resultRepository;
				shlRepository.close();
			}

		});
		btnSave.setText("Save");

		Group group = new Group(composite, SWT.NONE);
		GroupLayout gl_composite = new GroupLayout(composite);
		gl_composite.setHorizontalGroup(gl_composite
				.createParallelGroup(GroupLayout.LEADING)
				.add(gl_composite.createSequentialGroup().addContainerGap(367, Short.MAX_VALUE).add(btnSave, GroupLayout.PREFERRED_SIZE, 94, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.RELATED)
						.add(btnCancel, GroupLayout.PREFERRED_SIZE, 94, GroupLayout.PREFERRED_SIZE).addContainerGap()).add(group, GroupLayout.DEFAULT_SIZE, 569, Short.MAX_VALUE));
		gl_composite.setVerticalGroup(gl_composite.createParallelGroup(GroupLayout.LEADING).add(
				GroupLayout.TRAILING,
				gl_composite.createSequentialGroup().add(group, GroupLayout.DEFAULT_SIZE, 384, Short.MAX_VALUE).add(18)
						.add(gl_composite.createParallelGroup(GroupLayout.BASELINE).add(btnCancel, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE).add(btnSave, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE)).addContainerGap()));

		Label lblId = new Label(group, SWT.NONE);
		lblId.setBounds(10, 25, 80, 13);
		lblId.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblId.setText("ID");

		textID = new Text(group, SWT.BORDER);
		textID.setText(GuiUtils.formateNull(resultRepository.getId()));
		textID.addKeyListener(new KeyAdapter() {
			public final void keyReleased(KeyEvent e) {
				resultRepository.setId(textID.getText());
				if (resultRepository.getId().trim().length() == 0) {
					labelWarning.setText("Repository ID can't be empty");
					btnSave.setEnabled(false);
				} else {
					if (existRepositoryId(resultRepository)) {
						labelWarning.setText("Repository ID already exists");
						btnSave.setEnabled(false);
					} else {
						labelWarning.setText("");
						btnSave.setEnabled(true);
					}
				}
			}
		});
		textID.setBounds(96, 22, 441, 19);

		Label labelHelpID = new Label(group, SWT.NONE);
		labelHelpID.setToolTipText("A unique identifier for a repository.");
		labelHelpID.setImage(ImageFactory.HELP);
		labelHelpID.setBounds(543, 22, 16, 19);

		Label lblName = new Label(group, SWT.NONE);
		lblName.setBounds(10, 50, 80, 13);
		lblName.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblName.setText("Name");

		textName = new Text(group, SWT.BORDER);
		textName.setText(GuiUtils.formateNull(resultRepository.getName()));
		textName.addKeyListener(new KeyAdapter() {
			public final void keyReleased(KeyEvent e) {
				resultRepository.setName(textName.getText());
			}
		});
		textName.setBounds(96, 47, 441, 19);

		Label labelHelpName = new Label(group, SWT.NONE);
		labelHelpName.setToolTipText("Human readable name of the repository.");
		labelHelpName.setImage(ImageFactory.HELP);
		labelHelpName.setBounds(543, 44, 16, 19);

		Label lblUrl = new Label(group, SWT.NONE);
		lblUrl.setText("URL");
		lblUrl.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblUrl.setBounds(10, 75, 80, 13);

		buttonTestURL = new Button(group, SWT.NONE);
		textURL = new Text(group, SWT.BORDER);
		textURL.setText(GuiUtils.formateNull(resultRepository.getUrl()));
		buttonTestURL.setEnabled(textURL.getText().trim().length() != 0);
		textURL.addKeyListener(new KeyAdapter() {
			public final void keyReleased(KeyEvent e) {
				resultRepository.setUrl(textURL.getText());
				if (textURL.getText().trim().length() != 0) {
					try {
						new java.net.URL(textURL.getText());
						buttonTestURL.setEnabled(true);
					} catch (Exception ex) {
						buttonTestURL.setEnabled(false);
					}
				} else {
					buttonTestURL.setEnabled(false);
				}
			}
		});
		textURL.setBounds(96, 72, 400, 19);

		Label labelHelpURL = new Label(group, SWT.NONE);
		labelHelpURL.setToolTipText("The url of the repository.");
		labelHelpURL.setImage(ImageFactory.HELP);
		labelHelpURL.setBounds(543, 69, 16, 19);

		buttonTestURL.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
			}
		});
		buttonTestURL.setBounds(502, 70, 35, 23);
		buttonTestURL.setText("...");

		Label lblLayout = new Label(group, SWT.NONE);
		lblLayout.setBounds(10, 100, 80, 13);
		lblLayout.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblLayout.setText("Layout");

		Label labelHelpLayout = new Label(group, SWT.NONE);
		labelHelpLayout.setToolTipText("The type of layout this repository uses for locating and storing artifacts - can be \"legacy\" or \"default\". ");
		labelHelpLayout.setImage(ImageFactory.HELP);
		labelHelpLayout.setBounds(543, 97, 16, 19);

		Group grpSnapshots = new Group(group, SWT.NONE);
		grpSnapshots.setText("Snapshots");
		grpSnapshots.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		grpSnapshots.setBounds(10, 119, 551, 112);

		final Button btnSnapshotsEnabled = new Button(grpSnapshots, SWT.CHECK);
		btnSnapshotsEnabled.setSelection(resultRepository.getSnapshots().isEnabled());
		btnSnapshotsEnabled.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		btnSnapshotsEnabled.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetDefaultSelected(SelectionEvent e) {
				resultRepository.getSnapshots().setEnabled(btnSnapshotsEnabled.getSelection());
			}
		});
		btnSnapshotsEnabled.setBounds(10, 21, 85, 16);
		btnSnapshotsEnabled.setText("enabled");

		Label lblSnapshotsUpdatepolicy = new Label(grpSnapshots, SWT.NONE);
		lblSnapshotsUpdatepolicy.setBounds(10, 43, 95, 13);
		lblSnapshotsUpdatepolicy.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblSnapshotsUpdatepolicy.setText("Update Policy");

		textSnapshotsUpdatePolicy = new Text(grpSnapshots, SWT.BORDER);
		textSnapshotsUpdatePolicy.setText(GuiUtils.formateNull(resultRepository.getSnapshots().makeUpdatePolicy()));
		textSnapshotsUpdatePolicy.addKeyListener(new KeyAdapter() {
			public final void keyReleased(KeyEvent e) {
				resultRepository.getSnapshots().setUpdatePolicy(textSnapshotsUpdatePolicy.getText());
			}
		});
		textSnapshotsUpdatePolicy.setBounds(121, 40, 396, 19);

		Label labelHelpSnapshotsUpdatePolicy = new Label(grpSnapshots, SWT.NONE);
		labelHelpSnapshotsUpdatePolicy.setToolTipText("The frequency for downloading updates - can be \"always\", \"daily\" (default), \"interval:XXX\" (in minutes) or \"never\" (only if it doesn't exist locally).");
		labelHelpSnapshotsUpdatePolicy.setImage(ImageFactory.HELP);
		labelHelpSnapshotsUpdatePolicy.setBounds(523, 37, 16, 19);

		Label lblSnapshotsChecksumPolicy = new Label(grpSnapshots, SWT.NONE);
		lblSnapshotsChecksumPolicy.setBounds(10, 68, 108, 13);
		lblSnapshotsChecksumPolicy.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblSnapshotsChecksumPolicy.setText("Checksum Policy");

		final Combo comboSnapshotsChecksumPolicy = new Combo(grpSnapshots, SWT.NONE | SWT.READ_ONLY);
		comboSnapshotsChecksumPolicy.setItems(new String[] { "", ChecksumPolicy.FAIL.toString(), ChecksumPolicy.WARM.toString() });

		if (resultRepository.getSnapshots().getChecksumPolicy() == ChecksumPolicy.FAIL) {
			comboSnapshotsChecksumPolicy.select(1);
		} else if (resultRepository.getSnapshots().getChecksumPolicy() == ChecksumPolicy.WARM) {
			comboSnapshotsChecksumPolicy.select(2);
		} else {
			comboSnapshotsChecksumPolicy.select(0);
		}
		comboSnapshotsChecksumPolicy.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetDefaultSelected(SelectionEvent e) {
				String item = comboSnapshotsChecksumPolicy.getItem(comboSnapshotsChecksumPolicy.getSelectionIndex());
				resultRepository.getSnapshots().setChecksumPolicy(item);
			}
		});

		comboSnapshotsChecksumPolicy.setBounds(121, 65, 396, 22);

		Label labelHelpSnapshotsChecksuPolicy = new Label(grpSnapshots, SWT.NONE);
		labelHelpSnapshotsChecksuPolicy.setToolTipText("What to do when verification of an artifact checksum fails - warn, fail, etc. Valid values are \"fail\" or \"warn\".");
		labelHelpSnapshotsChecksuPolicy.setImage(ImageFactory.HELP);
		labelHelpSnapshotsChecksuPolicy.setBounds(523, 62, 16, 19);

		Label labelSnapshotsEnabled = new Label(grpSnapshots, SWT.NONE);
		labelSnapshotsEnabled.setToolTipText("Whether to use this repository for downloading this type of artifact. ");
		labelSnapshotsEnabled.setImage(ImageFactory.HELP);
		labelSnapshotsEnabled.setBounds(523, 21, 16, 19);

		labelWarning = new Label(group, SWT.NONE);
		labelWarning.setBounds(10, 355, 549, 13);
		labelWarning.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
		labelWarning.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD | SWT.ITALIC));

		Group groupRelease = new Group(group, SWT.NONE);
		groupRelease.setText("Releases");
		groupRelease.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		groupRelease.setBounds(10, 237, 551, 112);

		final Button buttonReleasesEnabled = new Button(groupRelease, SWT.CHECK);
		buttonReleasesEnabled.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		buttonReleasesEnabled.setSelection(resultRepository.getReleases().isEnabled());
		buttonReleasesEnabled.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetDefaultSelected(SelectionEvent e) {
				resultRepository.getReleases().setEnabled(buttonReleasesEnabled.getSelection());
			}
		});
		buttonReleasesEnabled.setText("enabled");
		buttonReleasesEnabled.setBounds(10, 21, 85, 16);

		Label labelReleasesUpdatePolicy = new Label(groupRelease, SWT.NONE);
		labelReleasesUpdatePolicy.setText("Update Policy");
		labelReleasesUpdatePolicy.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		labelReleasesUpdatePolicy.setBounds(10, 43, 95, 13);

		textReleasesUpdatePolicy = new Text(groupRelease, SWT.BORDER);
		textReleasesUpdatePolicy.setText(GuiUtils.formateNull(resultRepository.getReleases().makeUpdatePolicy()));
		textReleasesUpdatePolicy.addKeyListener(new KeyAdapter() {
			public final void keyReleased(KeyEvent e) {
				resultRepository.getReleases().setUpdatePolicy(textReleasesUpdatePolicy.getText());
			}
		});
		textReleasesUpdatePolicy.setBounds(123, 40, 394, 19);

		Label labelHelpReleasesUpdatePolicy = new Label(groupRelease, SWT.NONE);
		labelHelpReleasesUpdatePolicy.setToolTipText("The frequency for downloading updates - can be \"always\", \"daily\" (default), \"interval:XXX\" (in minutes) or \"never\" (only if it doesn't exist locally).");
		labelHelpReleasesUpdatePolicy.setImage(ImageFactory.HELP);
		labelHelpReleasesUpdatePolicy.setBounds(523, 37, 16, 19);

		Label labelReleaseChecksumPolicy = new Label(groupRelease, SWT.NONE);
		labelReleaseChecksumPolicy.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		labelReleaseChecksumPolicy.setText("Checksum Policy");
		labelReleaseChecksumPolicy.setBounds(10, 68, 95, 13);

		final Combo comboReleasesChecksumPolicy = new Combo(groupRelease, SWT.NONE | SWT.READ_ONLY);
		if (resultRepository.getReleases().getChecksumPolicy() == ChecksumPolicy.FAIL) {
			comboReleasesChecksumPolicy.select(1);
		} else if (resultRepository.getReleases().getChecksumPolicy() == ChecksumPolicy.WARM) {
			comboReleasesChecksumPolicy.select(2);
		} else {
			comboReleasesChecksumPolicy.select(0);
		}
		comboReleasesChecksumPolicy.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetDefaultSelected(SelectionEvent e) {
				String item = comboReleasesChecksumPolicy.getItem(comboReleasesChecksumPolicy.getSelectionIndex());
				resultRepository.getReleases().setChecksumPolicy(item);
			}
		});
		comboReleasesChecksumPolicy.setBounds(123, 65, 394, 22);

		Label labelHelpReleasesChecksumPolicy = new Label(groupRelease, SWT.NONE);
		labelHelpReleasesChecksumPolicy.setToolTipText("What to do when verification of an artifact checksum fails - warn, fail, etc. Valid values are \"fail\" or \"warn\".");
		labelHelpReleasesChecksumPolicy.setImage(ImageFactory.HELP);
		labelHelpReleasesChecksumPolicy.setBounds(523, 65, 16, 19);

		Label label = new Label(groupRelease, SWT.NONE);
		label.setToolTipText("Whether to use this repository for downloading this type of artifact. ");
		label.setImage(ImageFactory.HELP);
		label.setBounds(523, 18, 16, 19);

		final Combo comboLayout = new Combo(group, SWT.NONE | SWT.READ_ONLY);
		comboLayout.setItems(new String[] { "", "default", "legacy" });

		if (resultRepository.getLayout() == Layout.DEFAULT) {
			comboLayout.select(1);
		} else if (resultRepository.getLayout() == Layout.LEGACY) {
			comboLayout.select(2);
		} else {
			comboLayout.select(0);
		}
		comboLayout.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetDefaultSelected(SelectionEvent e) {
				resultRepository.setLayout(Layout.parse(comboLayout.getItem(comboLayout.getSelectionIndex())));
			}
		});
		comboLayout.setBounds(96, 97, 441, 22);

		composite.setLayout(gl_composite);

		shlRepository.setLayout(gl_shlRepository);

	}

	private final boolean existRepositoryId(Repository resultRepository) {
		for (Repository existsRepo : listOfRepositories) {
			if (this.existsRepository != null) {
				if (!this.existsRepository.equals(existsRepo)) {
					if (GuiUtils.formateNull(existsRepo.getId()).trim().equalsIgnoreCase(GuiUtils.formateNull(resultRepository.getId().trim()))) {
						return true;
					}
				}
			} else {
				if (GuiUtils.formateNull(existsRepo.getId()).trim().equalsIgnoreCase(GuiUtils.formateNull(resultRepository.getId().trim()))) {
					return true;
				}
			}
		}
		return false;
	}
}
